package club.zhcs.capture.biz.img.impl;

import static club.zhcs.capture.vo.Consts.SystemValues.PAGESIZE;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;

import org.nutz.castor.Castors;
import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.lang.LoopException;
import org.nutz.lang.Times;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;

import club.zhcs.capture.MD5.MD5FileUtil;
import club.zhcs.capture.bean.Material;
import club.zhcs.capture.bean.Material.Type;
import club.zhcs.capture.biz.img.IMaterialService;
import club.zhcs.capture.dao.IMaterialDao;
import club.zhcs.capture.ocr.BaiduOcr.IDCard;
import club.zhcs.capture.qiniu.GJUploader;
import club.zhcs.capture.vo.Consts.SystemValues;

import com.dgj.utils.collection.Lists;
import com.dgj.utils.db.SqlActuator;
import com.dgj.utils.entries.Result;
import com.dgj.utils.file.Images;
import com.dgj.utils.web.pager.Pager;

@IocBean
public class MaterialService implements IMaterialService {

	@Inject
	IMaterialDao materialDao;

	@Override
	public Result uploadImg(NutMap data, final IDCard card) {
		System.err.println(data.keySet());
		final String qrcode = data.getString("qrcode");
		final String docType = data.getString("docType");
		final String deviceId = data.getString("deviceId");
		final String batchNo = R.UU16();
		final Type type = Castors.me().castTo(docType, Type.class);
		final int id = data.getInt("userId");
		String imageData = data.getString("dataArray");
		List<LinkedHashMap> dataArray = Json.fromJson(List.class, imageData);

		final List<Material> materials = Lists.newArrayList();
		Lang.each(dataArray, new Each<LinkedHashMap>() {

			@Override
			public void invoke(int index, LinkedHashMap data_, int length) throws ExitLoop, ContinueLoop, LoopException {
				NutMap data = NutMap.WRAP(data_);
				if (data.size() == 0) {
					return;
				}
				Material temp = new Material();
				temp.setBatchNo(batchNo);
				temp.setDeviceId(deviceId);
				temp.setSerial(qrcode);
				temp.setType(type);
				temp.setUploadTime(Times.now());
				temp.setUploaderId(id);
				temp.setRemark(data.getString("remark"));
				if (type == Type.IDCARD) {
					temp.setRemark(Json.toJson(card, JsonFormat.compact()));
				}
				String imageData = data.getString("data");
				String p = Times.format("yyyy/MM/dd", Times.now()) + File.separator + (qrcode == null ? R.UU16() : qrcode);// 年/月/日/二维码,如果非二维码数据则随机生成目录
				File file = new File(SystemValues.FILE_PATH + File.separator + p + File.separator + index + ".png");
				Files.createFileIfNoExists(file);
				Images.GenerateImage(imageData.substring(imageData.indexOf("base64") + 7), file);// 此时文件保存到了本地
				temp.setFilePath(file.getPath());
				try {
					temp.setHash(MD5FileUtil.getFileMD5String(file));
				} catch (IOException e) {
					e.printStackTrace();
				}
				temp.setFileKey(GJUploader.upload(file));
				materials.add(temp);
			}
		});
		materialDao.getDao().insert(materials);
		return Result.success();
	}

	@Override
	public Pager<Record> listByPage(int page, int userId) {
		Pager<Record> pager = new Pager<Record>(PAGESIZE, page);
		Sql sql = Sqls
				.create("SELECT m.*, COUNT(m.m_uuid) AS pic_count, u.u_real_name FROM gj_material m LEFT JOIN gj_user u ON m.m_uploader_id = u.id WHERE m.m_uploader_id = @userId GROUP BY m.m_uuid LIMIT @pageStart ,@pageSize");
		sql.params().set("pageStart", (page - 1) * PAGESIZE);
		sql.params().set("pageSize", PAGESIZE);
		sql.params().set("userId", userId);
		List<Record> records = SqlActuator.runReport(sql, materialDao.getDao());
		Lang.each(records, new Each<Record>() {

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				record.set("m_type", Castors.me().castTo(record.getString("m_type"), Type.class));
			}
		});
		pager.setEntities(records);
		pager.setCount(SqlActuator.runUnq("SELECT COUNT(*) FROM (SELECT * FROM gj_material GROUP BY m_uuid) r", materialDao.getDao()));
		return pager;
	}

	@Override
	public List<Material> listByUUID(String uuid) {
		return materialDao.search(Cnd.where("batchNo", "=", uuid));
	}

	@Override
	public Pager<Record> search(int page, String key, int userId) {
		Pager<Record> pager = new Pager<Record>(PAGESIZE, page);
		key = String.format("%%%s%%", key);
		Condition cnd = Cnd.where("m.m_uploader_id", "=", userId).or("m.m_serial", "like", key).or("m.m_uuid", "like", key);
		Sql sql = Sqls
				.create("SELECT m.*, COUNT(m.m_uuid) AS pic_count, u.u_real_name FROM gj_material m LEFT JOIN gj_user u ON m.m_uploader_id = u.id $condition GROUP BY m.m_uuid LIMIT @pageStart ,@pageSize");
		sql.params().set("pageStart", (page - 1) * PAGESIZE);
		sql.params().set("pageSize", PAGESIZE);
		sql.setCondition(cnd);
		List<Record> records = SqlActuator.runReport(sql, materialDao.getDao());
		Lang.each(records, new Each<Record>() {

			@Override
			public void invoke(int index, Record record, int length) throws ExitLoop, ContinueLoop, LoopException {
				record.set("m_type", Castors.me().castTo(record.getString("m_type"), Type.class));
			}
		});
		pager.setEntities(records);
		Sql sql_ = Sqls.create("SELECT COUNT(*) FROM (SELECT * FROM gj_material m $condition GROUP BY m.m_uuid) r");
		sql_.setCondition(cnd);
		pager.setCount(SqlActuator.runUnq(sql_, materialDao.getDao()));
		return pager;
	}
}
